#pragma once
#include <unordered_map>
#include "Connection.hpp"
#include "Epoller.hpp"
#include <memory>

static const int gmaxevents = 5; 
class TcpServer
{
public:
    TcpServer()
        :_epoller(new Epoller()), _isrunning(false)
    {
        _isrunning = true; //无init, 暂时在这
    }
    void AddConnction(Connection* conn)
    {
        _connections[conn->GetSockfd()] = conn;
        _epoller->AddEvent(conn->GetSockfd(), conn->GetEvents());   //不要忘记了，关心上他
    }
    void LoopOnce(int n)
    {
        for(int i = 0; i < n; i++)
        {
            int fd = _recvs[i].data.fd;
            uint32_t events = _recvs[i].events;
            if((events & EPOLLERR) || (events & EPOLLHUP))
                events |= EPOLLIN;  //让它去EPOLLIN里报错
            
            if(events & EPOLLIN)
                _connections[fd]->_recver(_connections[fd]);
            if(events & EPOLLOUT)
                _connections[fd]->_sender(_connections[fd]);
        }
    }
    void Dispatch()
    {
        while(_isrunning)
        {
            _epoller->PrintDebug();
            int n = _epoller->Wait(_recvs, gmaxevents, -1);
            LoopOnce(n);
        }
    }
    void ReNewConnection(int fd, uint32_t events)
    {
        _epoller->ModEvent(fd, events); 
        _connections[fd]->SetEvents(events);    
    }
    void RemoveConnection(int fd)
    {
        _epoller->DelEvent(fd);         //删除内核的管理
        _connections.erase(fd);         //删除链接指向的管理
    }
    ~TcpServer()
    {}
private:
    std::unique_ptr<Epoller> _epoller;
    std::unordered_map<int, Connection*> _connections;  //链接的管理
    epoll_event _recvs[gmaxevents];
    bool _isrunning;
};